// 使用国密算法sm2加密传参
const sm2 = require('miniprogram-sm-crypto').sm2;
// 上报记录
let trackRecord = {}

const dh_track = {
    // 用户生成唯一字符串的字符集
    charsStr: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
    // imei长度
    imeiLen: 17,
    // sdk版本
    sdkVersion: '1.0.0',
    // 基础配置
    baseConfig: {
        serveUrl: '', // 数据上报地址
        switch: true, // 是否开启上报
        debugger: false, // 是否开启调试
        publicKey: '', // 加密密钥
        privateKey: ''
    },
    // 上报的公共参数
    pubParams: {
        eventName: '', // 事件名称
        isNew: '', // 是否新用户 1新用户 0老用户
        uid: '', // 用户id 
        localTime: new Date().getTime(), // 事件上报时的本地时间戳
        imei: '', // 设备唯一标识
        title: '', // 页面标题
        sh: '', // 屏幕高度
        sw: '', //屏幕宽度
        logId: '', // 事件上报的id，唯一性
        system: '', // 系统：ios 10.0.1
        model: '', // 设备型号：iPhone 6
        brand: '', // 品牌
        url: '', // 当前页面路径
        referrer: '', //上一个页面路径
        net: '', // 网络状态 wifi
        wxVersion: '', //微信版本
    },
    // 页面数据
    pageParams: {
        title: '', // 页面标题
        url: '', // 小程序 path
        duringTime: 0, // 页面停留时间
        pageId: '', // 页面id 同url
    },
    // 仅需获取一次的数据
    onceParams: [
        'imei', 'sh', 'sw', 'model', 'system', 'brand', 'isNew', 'wxVersion', 'sdkVersion'
    ],
    // 每次上报都要重新获取的数据
    repeatParams: [
        'localTime', 'logId', 'url', 'referrer', 'title', 'pageId', 'net'
    ],

    // 获取上报参数的方法集合
    paramFnc: {
        // sdk版本
        sdkVersion() {
            dh_track.pubParams.sdkVersion = dh_track.sdkVersion;
        },
        // 微信版本
        wxVersion() {
            dh_track.pubParams.wxVersion = wx.getAppBaseInfo().version;
        },
        // 网络环境
        net() {
            var net = null;
            wx.getNetworkType({
                success(res) {
                    net = res.networkType;
                    dh_track.pubParams.net = net;
                }
            });
        },
        // 品牌
        brand() {
            const brand = wx.getDeviceInfo().brand;
            dh_track.pubParams.brand = brand;
        },
        // 系统
        system() {
            const system = wx.getDeviceInfo().system;
            dh_track.pubParams.system = system;
        },
        // 设备型号
        model() {
            const model = wx.getDeviceInfo().model;
            dh_track.pubParams.model = model;
        },
        // 屏幕宽度
        sw() {
            const sw = wx.getWindowInfo().screenWidth;
            dh_track.pubParams.sw = sw;
        },
        // 屏幕高度
        sh() {
            const sh = wx.getWindowInfo().screenHeight;
            dh_track.pubParams.sh = sh;
        },
        // 上报事件
        localTime() {
            dh_track.pubParams.localTime = new Date().getTime();
        },
        // 设置 logId
        logId() {
            dh_track.paramFnc.imei();
            dh_track.pubParams.logId = dh_track.pubParams.imei + '_' + new Date().getTime()
        },
        // 设置 isNew 1新用户 0老用户
        isNew() {
            var isNew = wx.getStorageSync('dh_track_isNew');
            if (isNew == 'old') {
                // 有本地存储则为老用户
                isNew = 0;
            } else {
                wx.setStorageSync('dh_track_isNew', 'old');
                isNew = 1;
            }
            dh_track.pubParams.isNew = isNew;
        },
        // 设置 imei
        imei() {
            var _imei = wx.getStorageSync('dh_track_imei');
            if (_imei) {
                dh_track.pubParams.imei = _imei;
            } else {
                // 初始化sdk时随机生成一个尽可能唯一性且永久存储在本地的字符串
                _imei = '';
                const _charsArr = dh_track.charsStr.split('');
                const _len = _charsArr.length;
                const _imeiLen = dh_track.imeiLen;
                for (let i = 0; i < _imeiLen; i++) {
                    let _char = _charsArr[Math.floor(Math.random() * _len)];
                    _imei += _char;
                }
                dh_track.pubParams.imei = _imei;
                wx.setStorageSync('dh_track_imei', _imei);
            }
        },
        // 当前页面的path（url）
        url() {
            try {
                let page = getCurrentPages();
                let _path = page[page.length - 1].route;
                dh_track.pubParams.url = _path;
                dh_track.pageParams.url = _path;
                return _path
            } catch (err) {
                // dh_track.baseConfig.debugger && console.log('url-err:', err)
                dh_track.pubParams.url = ''
                dh_track.pageParams.url = ''
                return ''
            }
        },
        // 上一个页面的path（url）
        referrer() {
            try {
                let page = getCurrentPages();
                if (page.length < 2) return '';
                let _path = page[page.length - 2].route;
                dh_track.pubParams.referrer = _path;
                return _path
            } catch (err) {
                // dh_track.baseConfig.debugger && console.log('referrer-err:', err)
                dh_track.pubParams.referrer = ''
                return ''
            }
        },
        // 获取页面标题
        title() {
            try {
                // 微信没有提供获取小程序页面标题的api，自己实现需要考虑报错阻塞
                let page = getCurrentPages();
                let _path = page[page.length - 1].route + '.html';
                let _title = __wxConfig.page[_path].window.navigationBarTitleText;
                dh_track.pubParams.title = _title;
                dh_track.pageParams.title = _title;
                return _title
            } catch (err) {
                // dh_track.baseConfig.debugger && console.log('title-err:', err)
                dh_track.pubParams.title = ''
                dh_track.pageParams.title = ''
                return ''
            }

        },
        // 获取页面id (小程序采用页面path作为id)
        pageId() {
            try {
                let page = getCurrentPages();
                let _path = page[page.length - 1].route;
                dh_track.pageParams.pageId = _path;
                return _path
            } catch (err) {
                // dh_track.baseConfig.debugger && console.log('pageId-err:', err)
                dh_track.pageParams.pageId = ''
                return ''
            }
        },
    },

    /**
     * 数据上报
     * @param {String} data
     */
    _sendData(data) {
        dh_track.baseConfig.debugger && console.log('加密前的数据：', data);
        const encryptData = sm2.doEncrypt(data, dh_track.baseConfig.publicKey, 0);
        dh_track.baseConfig.debugger && console.log('加密后的数据：', encryptData);
        // 解密数据
        let decryptData = sm2.doDecrypt(encryptData, dh_track.baseConfig.privateKey, 0)
        dh_track.baseConfig.debugger && console.log('解密后的数据：', decryptData);
        // 上报地址拼接
        const urlStr = dh_track.baseConfig.serveUrl + '/log.gif?logType=web&log=' + encryptData
            // 创建canvas 实例
        const canvas = wx.createOffscreenCanvas({ type: '2d', width: 1, height: 1 })
            // 创建一个图片
        const image = canvas.createImage()
            // 图片加载失败重复加载
        image.onerror = function() {
            if (dh_track.baseConfig.handleFail) image.src = urlStr
        };
        image.src = urlStr
    },

    /**
     * 合并并加密要上报的参数
     * @param {Object} params
     */
    _mergeParams(params) {
        // 公共参数拼接
        const data = Object.assign(this.pubParams, {
            page: JSON.stringify(this.pageParams)
        }, params);
        this.baseConfig.debugger && console.log('上报的数据:', data);
        return JSON.stringify(data);
        // 加密数据
        // return sm2Encrypt(JSON.stringify(data),this.baseConfig.publicKey,0);
    },

    // 仅需要获取一次的参数，比如设备型号等固定不变的数据 
    _getOnceParams() {
        let arr = this.onceParams;
        for (let i = 0; i < arr.length; i++) {
            if (typeof dh_track.paramFnc[arr[i]] === 'function') {
                dh_track.paramFnc[arr[i]]();
            }
        }
    },

    // 获取每次上报都有变化的数据，如页面标题、上报时间、事件id等 
    _getRepeatParams() {
        let arr = this.repeatParams;
        for (let i = 0; i < arr.length; i++) {
            if (typeof dh_track.paramFnc[arr[i]] === 'function') {
                dh_track.paramFnc[arr[i]]();
            }
        }
    },

    // 设置页面数据
    _setPageParam(params) {
        if (params.duringTime) {
            dh_track.pageParams.duringTime = params.duringTime;
        }
    },

    /**
     * 根据业务需求设置额外的上报参数
     * @param {Object} params
     */
    setParams(params) {
        for (let key in params) {
            if (key && params[key]) {
                this.pubParams[key] = params[key];
            }
        }
        return this;
    },

    /**
     * 上报方法
     * @param {String} 事件名称
     * @param {Object} 上报的数据
     */
    trackEvent(eventName, params) {
        // 上报记录
        if (this.baseConfig.switch && this.baseConfig.debugger) {
            if (trackRecord[eventName]) {
                trackRecord[eventName]++
            } else {
                trackRecord[eventName] = 1
            }
            console.log('事件上报记录', trackRecord)
        }
        if (!dh_track.baseConfig.switch) return
            // 需要重复获取的字段
        dh_track._getRepeatParams(eventName);
        dh_track.pubParams.eventName = eventName;
        params.eventName = eventName;
        // 设置页面数据
        // eventName == 'viewPage' && dh_track._setPageParam(params);
        dh_track._setPageParam(params);
        let keysArr = [];
        let paramsStr = '';
        if (params) {
            keysArr = Object.keys(params);
            if (keysArr.length > 0) {
                paramsStr = JSON.stringify(params);
            }
        }
        dh_track._sendData(dh_track._mergeParams({
            actions: paramsStr
        }));


    },

    /**
     * 初始化配置
     * @param {Object} params
     */
    init(params) {
        // 设置基础配置，初始化sdk时传入
        for (let key in params) this.baseConfig[key] = params[key];
        // 设置仅需要获取一次的上报数据
        this._getOnceParams();
        return this;
    },
};

export default dh_track;